﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MaxLeaf.Platform.DataContract;
using CommonsLib.DB;
using MaxLeaf.Platform.DALImplementation;
using MaxLeaf.Platform.Functions;
using CommonsLib.Utility;
using MaxLeaf.Platform.Commons;
using MaxLeaf.Platform.Contract;
using CommonsLib.Utility;
using CommonsLib.Settings;

namespace MaxLeaf.Platform.BLLImplementation
{
    public class CategroyApproBLL :   ICategroyAppro
    {
        public CategroyApproDataModel Confirm(CategroyApproDataModel model)
        {
            using (System.Transactions.TransactionScope ts = DataFunc.CreateTransactionScope())
            {
                using (DBAccess dbcon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPSEOrder)))
                {
                    try
                    {
                        #region  先取得这个领用需要单的表头数据
                        imStoresReqHdrDataModel imOrigReqHdrModel = new imStoresReqHdrDataModel();
                        imOrigReqHdrModel = (imStoresReqHdrDataModel)new imStoresReqHdrBLL().Select(imOrigReqHdrModel, CvtFunc.ToInt(model.BillFinterID));
                        #endregion

                        //dbcon.BeginTrans();
                        CategroyApproDAL scpDAL = new CategroyApproDAL();
                        scpDAL.Confirm(dbcon, model);
                        if (model.Posted)
                        {
                            string strSQL = "";// "UPDATE imStoresReqHdr_Group SET Posted=1 where FinterID = '" + model.Group_FInterID + "'";
                            //dbcon.ExecuteSql(strSQL);
                            int intCompanyID = mCompanyBLL.GetParentCompanyID(CvtFunc.ToInt(model.CompanyID));
                            if (CvtFunc.ToInt(new CategroyApproDAL().GetMaxApproLevel(dbcon, model, intCompanyID)) == 0) // 如果没有设置多级审核则，则需要直接确认这个单据
                            {
                                intCompanyID = 0;
                            }
                            if (intCompanyID > 0) //如果有总公司,全部产生一套新的到总公司去等待审核
                            {
                                if (!GeneratNewStoresReq(dbcon, imOrigReqHdrModel, intCompanyID, model))
                                {

                                    //dbcon.RollbackTrans();
                                    model.Posted = false;
                                    model.Success = false;
                                }
                                //else
                                //{
                                //    poReqHdrDataModel poHdr = new poReqHdrDataModel();
                                //    poHdr.CompanyID = imOrigReqHdrModel.CompanyID;
                                //    InitPoReqHdr(poHdr); 
                                //}
                            }
                            else //全部下推到领用出库单
                            {
                                imStoresOutputProcessor imStoreBLL = new imStoresOutputProcessor();
                                //string strSQL="select CompanyID from imStoresReqHdr where FinterID ='"+ imOrigReqHdrModel.OrigFInterID +"'";
                                //int intOrigCompanyID = CvtFunc.ToInt(dbcon.GetValue(strSQL));
                                //if ( intOrigCompanyID !=0) imOrigReqHdrModel.CompanyID = intOrigCompanyID;

                                string strOrigFinterID = dbcon.GetValue("Select OrigFinterID From imStoresReqHdr Where FInterID='" + model.BillFinterID + "'");
                                strSQL = "UPDATE imStoresReqHdr Set HeadPosted=1 WHERE FInterID='{0}'";
                                dbcon.ExecuteSql(string.Format(strSQL, strOrigFinterID));

                                strSQL = "UPDATE imStoresReqHdr Set HeadPosted=1 WHERE FInterID='{0}'";
                                dbcon.ExecuteSql(string.Format(strSQL, model.BillFinterID));

                                if (!imStoreBLL.GeneratNewStoreOutFromStoreReq(dbcon, imOrigReqHdrModel))
                                {
                                    //dbcon.RollbackTrans();
                                    model.Posted = false;
                                    model.Success = false;
                                }

                                //如果有些商品不够，则要产生一部分到采购需求单
                                int intOrigCompanyID = 0;
                                poReqProcessor poBLL = new poReqProcessor();
                                if (imOrigReqHdrModel.OrigFInterID > 0) //如果是总公司审核完下推的就，就用去找分公司的companyid
                                {
                                    strSQL = "UPDATE imStoresReqHdr_Group SET Posted= 1 where FInterID='" + imOrigReqHdrModel.OrigFInterID + "'";
                                    dbcon.ExecuteSql(strSQL);

                                    intOrigCompanyID = CvtFunc.ToInt(dbcon.GetValue("Select CompanyID From imStoresReqHdr Where FinterID='" + imOrigReqHdrModel.OrigFInterID + "'"));
                                    strSQL = "select Is_SeparateAccount from mCompany_info where companyid='" + intOrigCompanyID + "'";
                                    using (DBAccess dbBaseCon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPBase)))
                                    {
                                        if (CvtFunc.ToBoolean(dbBaseCon.GetValue(strSQL)))
                                        {
                                            imOrigReqHdrModel.CompanyID = intOrigCompanyID;
                                        }
                                        else
                                        {
                                            //intOrigCompanyID = 0;
                                            //imOrigReqHdrModel.CompanyID = CvtFunc.ToInt(dbcon.GetValue("Select CompanyID From imStoresReqHdr Where FinterID='" + imOrigReqHdrModel.OrigFInterID + "'"));
                                        }
                                    }
                                }
                                else  //如果是分公司自己的，不是总公司审核完下推的就，就用自己的companyid
                                {
                                    imOrigReqHdrModel.CompanyID = imOrigReqHdrModel.CompanyID;
                                }

                                if (!poBLL.GeneratPoReqDtlFromStoresReq(imOrigReqHdrModel, ( intOrigCompanyID ==0 ?  0 : intOrigCompanyID )  , dbcon))
                                {
                                    //dbcon.RollbackTrans();
                                    model.Posted = false;
                                    model.Success = false;
                                }
                            }
                        }
                        //    dbcon.CommitTrans();
                        //    dbcon.Close();
                    }
                    catch (Exception ex)
                    {
                        LogManager.Debug(ex.Message);                        
                    }
                }
                if (model.Success)
                {
                    ts.Complete();
                }
                return model;
            }
        }

        

#region 公司审核完成后，数据、业务的处理
        /// 1. （如果有总公司）这个采购申请单要提交到总公司的领用申请单来进行级别审批（审核）
        ///     重新生成（Insert）领用申请单表头（更换companyID 为总公司ID号），OrigCompanyID为子公司ID，OrigFInterID为原领用申请单表头FInterID
        ///     重新生成（Insert）领用申请单表体（更换companyID 为总公司ID号），OrigDtlID为子公司原领用申请单表体DtlID
        /// 2. （如果没有总公司，或总公司审核完成）所有Detail行要全部下推到领用出库单
        /// 3. （如果没有总公司，或总公司审核完成）库存不够的行要下推到采购单
        /// 
    #region 1. （如果有总公司）这个采购申请单要提交到总公司的领用申请单来进行级别审批（审核）
        ///     重新生成（Insert）领用申请单表头（更换companyID 为总公司ID号），OrigCompanyID为子公司ID，OrigFInterID为原领用申请单表头FInterID
        ///     重新生成（Insert）领用申请单表体（更换companyID 为总公司ID号），OrigDtlID为子公司原领用申请单表体DtlID
        private bool GeneratNewStoresReq(DBAccess dbcon, imStoresReqHdrDataModel imOrigReqHdrModel, int intCompanyID,CategroyApproDataModel model)
        {
            try
            {
                imStoresReqHdrDAL imDAL = new imStoresReqHdrDAL();
                imStoresReqHdrDataModel imNewHdrModel = new imStoresReqHdrDataModel();
                imStoresReqHdr_GroupDataModel imNewHdrGroupModel = new imStoresReqHdr_GroupDataModel();
                imNewHdrModel.CompanyID = intCompanyID;
                imNewHdrModel = (imStoresReqHdrDataModel)BaseBLL.GetDataModelBLL("imStoresReqHdrDataModel").InsertFinterID(imNewHdrModel);
                
                imStoresReqHdr_GroupBLL imGroupBLL= new imStoresReqHdr_GroupBLL ();

                #region 分公司在总公司的领用汇总单表头数据  
                if (model.Group_FInterID == 0)
                {
                    imNewHdrGroupModel.CompanyID = intCompanyID;
                    imNewHdrGroupModel.OrigCompanyID = imOrigReqHdrModel.CompanyID;
                    imNewHdrGroupModel.DocDate = DateTime.Now;
                    imNewHdrGroupModel.Posted = false;
                    imNewHdrGroupModel = (imStoresReqHdr_GroupDataModel)imGroupBLL.InsertFinterID(imNewHdrGroupModel);
                    imNewHdrGroupModel = (imStoresReqHdr_GroupDataModel)imGroupBLL.Update(imNewHdrGroupModel);
                    model.Group_FInterID = imNewHdrGroupModel.Key;
                }
                else
                {
                }
                
                #endregion

                imDAL.GeneratNewStoresReq(dbcon, imOrigReqHdrModel, imNewHdrModel,model);

                imStoresReqDtlDataModel imDtlModel = new imStoresReqDtlDataModel();
                List<Object> imStoreReqDtl = (List<Object>)BaseBLL.GetDataModelBLL("imStoresReqDtlDataModel").SelectDtl(imDtlModel, imOrigReqHdrModel.Key);
                for (int i = 0; i <= imStoreReqDtl.Count-1; i++)
                {
                    
                    imStoresReqDtlDataModel imNewModel = new imStoresReqDtlDataModel();
                    imStoresReqDtlDataModel imOrigDtlModel = imStoreReqDtl[i] as imStoresReqDtlDataModel;
                    if (imOrigDtlModel.Is_Delete == true) continue;
                    imNewModel = (imStoresReqDtlDataModel)new imStoresReqDtlBLL().InsertFinterID(imNewModel);
                    imDAL.GenetateNewStoresReqDtl(dbcon, imOrigDtlModel, imNewModel);

                    imNewModel.ForeignKey = imNewHdrModel.Key;
                    imNewModel.OrigDtlID = imOrigDtlModel.Key;
                    imDAL.Update(dbcon, imNewModel);
                }
                return true;
            }
            catch (Exception ex)
            {
                CommonsLib.Settings.LogManager.Error(ex);
                return false;
            }            
        }

    #endregion

    #region  2. （如果没有总公司，或总公司审核完成）所有Detail行要全部下推到领用出库单
           //3. （如果没有总公司，或总公司审核完成）库存不够的行要下推到采购单
        private bool InitPoReqHdr(poReqHdrDataModel poHdr)
        {
            if ( new imStoresReqHdrApproProcessor().InitPoReqHdr(poHdr))
            {
                return true ;
            }
            return false ;
        }

        private bool blnPostTo()
        {
            return true ;
        }

        private bool blnPostToPoReqHdr()
        {
            return true ;
        }

        private bool blnPostToStoresOut()
        {
            return true ;
        }
    #endregion


#endregion

        public CategroyApproDataModel UnConfirm(CategroyApproDataModel model)
        {
            using (DBAccess dbcon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPSEOrder)))
            {
                CategroyApproDAL scpDAL = new CategroyApproDAL();
                scpDAL.UnConfirm(dbcon, model);
                return model;
            }
        }

        #region ICategroyAppro 成员


        public CategroyApproDataModel DepartApproval(CategroyApproDataModel model)
        {
            using (DBAccess dbcon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPSEOrder)))
            {
                if (model.FinterIDType == (int)FinterIDType.StoresReq)
                {
                    CategroyApproDAL iDAL = new CategroyApproDAL();
                    model = iDAL.DepartApproval_StoreReq(dbcon, model);

                    if (model.Success)
                    {
                        if (CvtFunc.ToInt(iDAL.GetMaxApproLevel(dbcon, model, CvtFunc.ToInt(model.CompanyID))) == 0) // 如果没有设置多级审核则，则需要直接确认这个单据
                        {
                            return Confirm(model);
                        }
                    }
                }
                else if (model.FinterIDType == (int)FinterIDType.poReqHdr)
                {

                }
                else if (model.FinterIDType == (int)FinterIDType.OthersInput) //入库审核，写库存
                {
                    using (System.Transactions.TransactionScope ts = DataFunc.CreateTransactionScope())
                    {
                        //is_LocAppro
                        //dbcon.BeginTrans(); 
                        imOthersInputHdrDataModel imHdr = new imOthersInputHdrDataModel();
                        imHdr = (imOthersInputHdrDataModel)BaseBLL.GetDataModelBLL("imOthersInputHdrDataModel").Select(imHdr, CvtFunc.ToInt(model.BillFinterID));
                        imOthersInputDtlDataModel imDtlModel = new imOthersInputDtlDataModel();
                        List<Object> imStoreDtl = (List<Object>)BaseBLL.GetDataModelBLL("imOthersInputDtlDataModel").SelectDtl(imDtlModel, CvtFunc.ToInt(model.BillFinterID));

                        imOthersInputHdrBLL bllOthersInputHdr = new imOthersInputHdrBLL();
                        imOthersInputDtlBLL bllOthersInputDtl = new imOthersInputDtlBLL();

                        for (int i = 0; i <= imStoreDtl.Count - 1; i++)
                        {
                            imOthersInputDtlDataModel imOrigDtlModel = imStoreDtl[i] as imOthersInputDtlDataModel;

                            ImInvHistBLL imHistBLL = new ImInvHistBLL();
                            ImInvHistDataModel imHistDataModel = new ImInvHistDataModel();
                            imHistDataModel = (ImInvHistDataModel)new ImInvHistBLL().InsertFinterID(imHistDataModel); // iminvhist
                            imHistDataModel.BillID = imHdr.Key;
                            imHistDataModel.BillNo = imHdr.OrdNo;
                            imHistDataModel.CompanyID = imHdr.CompanyID;
                            imHistDataModel.EnterUnitID = imOrigDtlModel.UnitID;
                            imHistDataModel.HistDate = imHdr.DocDate;
                            imHistDataModel.ItemID = imOrigDtlModel.ItemID;
                            imHistDataModel.Price = imOrigDtlModel.Price / new ImInvMasterBLL().GetRateByItemID(imOrigDtlModel.ItemID, imOrigDtlModel.UnitID);
                            imHistDataModel.PriceInEnterUnit = imOrigDtlModel.Price;
                            imHistDataModel.Qty = imOrigDtlModel.ReqQty * new ImInvMasterBLL().GetRateByItemID(imOrigDtlModel.ItemID, imOrigDtlModel.UnitID);
                            imHistDataModel.QtyInEnterUnit = imOrigDtlModel.ReqQty;
                            imHistDataModel.Type = 2;
                            imHistDataModel.TypeID = imHdr.DocType;

                            int intStockUnitID = 0;
                            using (DBAccess dbBaseCon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPBase)))
                            {
                                intStockUnitID = CvtFunc.ToInt(dbBaseCon.GetValue("select StockUnitID from iminvmaster where FInterID='" + imHistDataModel.ItemID + "'"));
                            }
                            imHistDataModel.InitWtAvgCost = ImInvLocBLL.GetWtAvgCost(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID);

                            imHistDataModel.InitOnhand = ImInvLocBLL.GetAvail(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID, false, false);

                            ImInvLocBLL.UpdateWtAvgCostAndOnHand(CvtFunc.ToInt(model.CompanyID), imOrigDtlModel.ItemID, imOrigDtlModel.ReqQty, imOrigDtlModel.Price, imOrigDtlModel.UnitID);
                            imHistDataModel.FinalWtAvgCost = ImInvLocBLL.GetWtAvgCost(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID);
                            imHistDataModel.FinalOnhand = ImInvLocBLL.GetAvail(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID, false, false);

                            imHistBLL.Update(imHistDataModel);

                            bllOthersInputDtl.SetPosted(dbcon, imOrigDtlModel.Key);
                        }
                        bllOthersInputHdr.SetPosted(dbcon, imHdr.Key);
                        model.Posted = true;
                        //dbcon.CommitTrans();

                        ts.Complete();
                    }
                }
                else if (model.FinterIDType == (int)FinterIDType.OthersOutput) //出库审核，写库存
                {
                    using (System.Transactions.TransactionScope ts = DataFunc.CreateTransactionScope())
                    {
                        //is_LocAppro
                        //dbcon.BeginTrans();
                        imOthersOutputHdrDataModel imHdr = new imOthersOutputHdrDataModel();
                        imHdr = (imOthersOutputHdrDataModel)BaseBLL.GetDataModelBLL("imOthersOutputHdrDataModel").Select(imHdr, CvtFunc.ToInt(model.BillFinterID));
                        imOthersOutputDtlDataModel imDtlModel = new imOthersOutputDtlDataModel();
                        List<Object> imStoreDtl = (List<Object>)BaseBLL.GetDataModelBLL("imOthersOutputDtlDataModel").SelectDtl(imDtlModel, CvtFunc.ToInt(model.BillFinterID));

                        imOthersOutputHdrBLL bllOthersOutputHdr = new imOthersOutputHdrBLL();
                        imOthersOutputDtlBLL bllOthersOutputDtl = new imOthersOutputDtlBLL();

                        for (int i = 0; i <= imStoreDtl.Count - 1; i++)
                        {
                            imOthersOutputDtlDataModel imOrigDtlModel = imStoreDtl[i] as imOthersOutputDtlDataModel;

                            ImInvHistBLL imHistBLL = new ImInvHistBLL();
                            ImInvHistDataModel imHistDataModel = new ImInvHistDataModel();
                            imHistDataModel = (ImInvHistDataModel)new ImInvHistBLL().InsertFinterID(imHistDataModel); // iminvhist
                            imHistDataModel.BillID = imHdr.Key;
                            imHistDataModel.BillNo = imHdr.OrdNo;
                            imHistDataModel.CompanyID = imHdr.CompanyID;
                            imHistDataModel.EnterUnitID = imOrigDtlModel.UnitID;
                            imHistDataModel.HistDate = imHdr.DocDate;
                            imHistDataModel.ItemID = imOrigDtlModel.ItemID;
                            imHistDataModel.Price = imOrigDtlModel.Price / new ImInvMasterBLL().GetRateByItemID(imOrigDtlModel.ItemID, imOrigDtlModel.UnitID);
                            imHistDataModel.PriceInEnterUnit = imOrigDtlModel.Price;
                            imHistDataModel.Qty = -1 * imOrigDtlModel.ReqQty * new ImInvMasterBLL().GetRateByItemID(imOrigDtlModel.ItemID, imOrigDtlModel.UnitID);
                            imHistDataModel.QtyInEnterUnit = -1 * imOrigDtlModel.ReqQty;
                            imHistDataModel.Type = 1;
                            imHistDataModel.TypeID = imHdr.DocType;
                            int intStockUnitID = 0;
                            using (DBAccess dbBaseCon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPBase)))
                            {
                                intStockUnitID = CvtFunc.ToInt(dbBaseCon.GetValue("select StockUnitID from iminvmaster where FInterID='" + imHistDataModel.ItemID + "'"));
                            }

                            imHistDataModel.InitWtAvgCost = ImInvLocBLL.GetWtAvgCost(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID);
                            imHistDataModel.InitOnhand = ImInvLocBLL.GetAvail(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID, false, false);

                            if (-1 * (imHistDataModel.Qty) > imHistDataModel.InitOnhand)
                            {
                                throw new MaxLeafException("库存不够！");
                            }
                            ImInvLocBLL.UpdateOnHand(CvtFunc.ToInt(model.CompanyID), imOrigDtlModel.ItemID, -1 * imOrigDtlModel.ReqQty, imOrigDtlModel.Price, imOrigDtlModel.UnitID);

                            imHistDataModel.FinalWtAvgCost = ImInvLocBLL.GetWtAvgCost(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID);
                            imHistDataModel.FinalOnhand = ImInvLocBLL.GetAvail(imHdr.CompanyID, imOrigDtlModel.ItemID, intStockUnitID, false, false);

                            imHistBLL.Update(imHistDataModel);
                            bllOthersOutputDtl.SetPosted(dbcon, imOrigDtlModel.Key);
                        }

                        bllOthersOutputHdr.SetPosted(dbcon, imHdr.Key);
                        model.Posted = true;
                        //dbcon.CommitTrans(); 

                        ts.Complete();
                    }
                }
                return model;
            }
        }

        #endregion

        #region 是否需要其他出入库审校的验证
        public CategroyApproDataModel NeedInvLocApproval(CategroyApproDataModel model)
        {
            using (DBAccess dbcon = new DBAccess(DataFunc.GetConnectionInfo(Const.DB_SCPBase)))
            {
                string strSQL = string.Empty;
                strSQL = "Select count(*) from mUser_Main where CompanyID={0} and is_LocAppro=1";
                double dblCount = CvtFunc.ToDouble(dbcon.GetValue(string.Format(strSQL, model.CompanyID)));
                if (dblCount > 0)
                {
                    model.Success = true;
                }
                else
                {
                    model.Success = false;
                }
                return model;
            }
        }

        #endregion

    }
}
